package org.linlinjava.litemall.wx.web;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.xxl.sso.core.conf.Conf;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.brand.dto.BrandVO;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallAd;
import org.linlinjava.litemall.db.domain.LitemallBrand;
import org.linlinjava.litemall.db.domain.NewsPay;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.dto.NewsInfo;
import org.linlinjava.litemall.wx.service.HomeCacheManager;
import org.linlinjava.litemall.wx.service.WxGrouponRuleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 首页服务 包括商品  行业信息   求助信息  推介商户2 个
 */
@RestController
@RequestMapping("/wx/home")
@Validated
public class WxHomeController {
    private final Log logger = LogFactory.getLog(WxHomeController.class);

    @Autowired
    private LitemallAdService adService;

    @Autowired
    private LitemallGoodsService goodsService;
    @Autowired
    private LitemallBrandService brandService;
    @Autowired
    private LitemallTopicService topicService;
    @Autowired
    private LitemallCategoryService categoryService;
    @Autowired
    private WxGrouponRuleService grouponService;
    @Autowired
    private LitemallCouponService couponService;
    @Autowired
    private NewsPayService newsPayService;
    /**新增:求助内容版块*/
    @Autowired
    private LitemallSeekHelpService seekHelpService;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(9, 9, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);

    /**
     * 清除缓存..
     * @param key  litemall_cache
     * @return
     */
    @GetMapping("/cache")
    public Object cache(@NotNull String key) {
        if (!key.equals("litemall_cache")) {
            return ResponseUtil.fail();
        }

        // 清除缓存
        HomeCacheManager.clearAll();
        return ResponseUtil.ok("缓存已清除");
    }

/**
 * 首页数据
 * 用户已经登录时，非空。为登录状态为null
 * @return 首页数据
 */
  /*  @GetMapping("/index")
    public Object index(@LoginUser Integer userId) {
        //优先从缓存中读取
        if (HomeCacheManager.hasData(HomeCacheManager.INDEX)) {
            return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.INDEX));
        }
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        Callable<List> bannerListCallable = () -> adService.queryIndex();

        Callable<List> channelListCallable = () -> categoryService.queryChannel();

        Callable<List> couponListCallable;
        if(userId == null){
            couponListCallable = () -> couponService.queryList(0, 3);
        } else {
            couponListCallable = () -> couponService.queryAvailableList(userId,0, 3);
        }
        Callable<List> newGoodsListCallable = () -> goodsService.queryByNew(0, SystemConfig.getNewLimit());

        Callable<List> hotGoodsListCallable = () -> goodsService.queryByHot(0, SystemConfig.getHotLimit());

        Callable<List> brandListCallable = () -> brandService.query(0, SystemConfig.getBrandLimit());

        Callable<List> topicListCallable = () -> topicService.queryList(0, SystemConfig.getTopicLimit());

        //团购专区
        Callable<List> grouponListCallable = () -> grouponService.queryList(0, 5);

        Callable<List> floorGoodsListCallable = this::getCategoryList;

        FutureTask<List> bannerTask = new FutureTask<>(bannerListCallable);
        FutureTask<List> channelTask = new FutureTask<>(channelListCallable);
        FutureTask<List> couponListTask = new FutureTask<>(couponListCallable);
        FutureTask<List> newGoodsListTask = new FutureTask<>(newGoodsListCallable);
        FutureTask<List> hotGoodsListTask = new FutureTask<>(hotGoodsListCallable);
        FutureTask<List> brandListTask = new FutureTask<>(brandListCallable);
        FutureTask<List> topicListTask = new FutureTask<>(topicListCallable);
        FutureTask<List> grouponListTask = new FutureTask<>(grouponListCallable);
        FutureTask<List> floorGoodsListTask = new FutureTask<>(floorGoodsListCallable);

        executorService.submit(bannerTask);
        executorService.submit(channelTask);
        executorService.submit(couponListTask);
        executorService.submit(newGoodsListTask);
        executorService.submit(hotGoodsListTask);
        executorService.submit(brandListTask);
        executorService.submit(topicListTask);
        executorService.submit(grouponListTask);
        executorService.submit(floorGoodsListTask);

        Map<String, Object> entity = new HashMap<>();
        try {
            entity.put("banner", bannerTask.get());
            entity.put("channel", channelTask.get());
            entity.put("couponList", couponListTask.get());
            entity.put("newGoodsList", newGoodsListTask.get());
            entity.put("hotGoodsList", hotGoodsListTask.get());
            entity.put("brandList", brandListTask.get());
            entity.put("topicList", topicListTask.get());
            entity.put("grouponList", grouponListTask.get());
            entity.put("floorGoodsList", floorGoodsListTask.get());
            //缓存数据
            HomeCacheManager.loadData(HomeCacheManager.INDEX, entity);
        }
        catch (Exception e) {
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
        return ResponseUtil.ok(entity);
    }

    private List<Map> getCategoryList() {
        List<Map> categoryList = new ArrayList<>();
        List<LitemallCategory> catL1List = categoryService.queryL1WithoutRecommend(0, SystemConfig.getCatlogListLimit());
        for (LitemallCategory catL1 : catL1List) {
            List<LitemallCategory> catL2List = categoryService.queryByPid(catL1.getId());
            List<Integer> l2List = new ArrayList<>();
            for (LitemallCategory catL2 : catL2List) {
                l2List.add(catL2.getId());
            }

            List<LitemallGoods> categoryGoods;
            if (l2List.size() == 0) {
                categoryGoods = new ArrayList<>();
            } else {
                categoryGoods = goodsService.queryByCategory(l2List, 0, SystemConfig.getCatlogMoreLimit());
            }

            Map<String, Object> catGoods = new HashMap<>();
            catGoods.put("id", catL1.getId());
            catGoods.put("name", catL1.getName());
            catGoods.put("goodsList", categoryGoods);
            categoryList.add(catGoods);
        }
        return categoryList;
    }
*/

    /**
     * 首页 行业快报 >>> 收费
      * @param json  必须包含 page: 1   size: 10
     * @param request   请求头携带信息  Authorization : 22_0aaafa26e084452ca6431aea6b859e6e
     * @return
     */
    @PostMapping("ad")
    public Object ad(@RequestBody String json,HttpServletRequest request) {
        String sessionId = request.getHeader(Conf.SSO_SESSIONID);
        String userId;
        //以第一个下划线"_"切割(session)类似Authorization.. 得到 22 就是用户 ID
        if (!StringUtils.isEmpty(sessionId)&&!sessionId.equals("null")) {
            userId = sessionId.split("_")[0];
        }else{
            userId = null;
        }
        Integer page = JacksonUtil.parseInteger(json, "page");
        if(null == page || page < 0){ page=1;}
        Integer size = JacksonUtil.parseInteger(json, "size");
        if(null == size || size < 0){ page=10;}
        List<LitemallAd> litemallAds = adService.queryIndex(page,size);

        List<NewsInfo> newsInfos = new LinkedList<>();
        if (litemallAds!=null&&litemallAds.size()>0) {
            for (LitemallAd litemallAd : litemallAds) {
                Integer payStatus;
                NewsPay newsPay = null;
                if (userId!=null){
                    newsPay=newsPayService.findByNewsId(litemallAd.getId(),Integer.parseInt(userId));
                }
                if (newsPay!=null) {
                     payStatus=newsPay.getPayStatus();
                }else {
                     payStatus = 0;
                }
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                String timeSubstring = litemallAd.getUpdateTime().toString().substring(0, 10);
                NewsInfo newsInfo = new NewsInfo(litemallAd,payStatus);
                newsInfo.setLocalData(timeSubstring);
                newsInfos.add(newsInfo);
            }
            return ResponseUtil.okPageList(litemallAds,newsInfos);
        }
        return null;
    }

    

    /**
     *  2002.04 首页新增服务:求助版块.默认显示8条数据 .前端需求..点击某条不跳转..点击更多.去求助模块./wx/seekHelp
     * @param page     页数  1
     * @param limit    每页个数  8
     * @param sort    排序规则 只有  "add_time", "id"
     * @param order   ASC  DESC
     * @return
     */
    @GetMapping("/help")
    public Object seekHelp(@RequestParam(defaultValue = "1") Integer page,
                           @RequestParam(defaultValue = "8") Integer limit,
                           @Sort @RequestParam(defaultValue = "add_time") String sort,
                           @Order @RequestParam(defaultValue = "desc") String order){
        Map<String,String> serachMap=new HashMap<>();
        PageInfo pageInfo = seekHelpService.seekHelpList(serachMap, page, limit, sort, order);
        return ResponseUtil.ok(pageInfo);
    }


    /**
     *   新加字段  推介商户recommend
     * @param page     页数  1
     * @param limit    每页个数  2
     * @return
     */
    @GetMapping("/recommend")
    public Object recommendCompany(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "2") Integer limit){
        Page<LitemallBrand> litemallBrands = brandService.recommendCompany(page, limit);
        List<BrandVO> voList=new ArrayList<>();
        for (LitemallBrand litemallBrand : litemallBrands) {
            BrandVO brandVO = new BrandVO();
            BeanUtils.copyProperties(litemallBrand,brandVO);
            voList.add(brandVO);
        }
        return ResponseUtil.ok(voList);
    }


}